package org.springframework.prospring.ticket.web;

import org.springframework.prospring.ticket.web.AbstractReservationFieldRequestController;
import org.springframework.prospring.ticket.service.RegionManager;
import org.springframework.prospring.ticket.service.ClubManager;
import org.springframework.prospring.ticket.service.ReservationFieldRequest;
import org.springframework.prospring.ticket.domain.Club;
import org.springframework.prospring.ticket.domain.Turn;
import org.springframework.prospring.ticket.domain.user.User;
import org.springframework.prospring.ticket.common.Constant;
import org.springframework.prospring.ticket.common.KeyConstant;
import org.springframework.validation.Errors;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.util.WebUtils;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.sql.Timestamp;

/**
 * Form controller issuing a ReservationRequest on behalf of the user.
 * The user has selected a show, a price band and a date in the previous
 * screen(s) and this form controller will create the reservation
 * request based on this. Together with the amount of seats the user will
 * be selected, this form controller completes the request.<p>
 *
 * Input:
 * <ul>
 *   <li><code>performanceId</code>: the performance identifier</li>
 *   <li><code>priceBandId</code>: the price band identifier</li>
 * </ul>
 * Error conditions:
 * <ul>
 *  <li>When not enough seats are available anymore</li>
 * </ul>
 */
public class ReserveFieldStep5Controller extends AbstractReservationFieldRequestController {


/*
    // the Region manager service this controller uses.
    private RegionManager regionManager;

    // the Club manager service this controller uses.
    private ClubManager clubManager;
*/

    /*
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
	 */
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep5Controller.formBackingObject");
        }
        return getReservationRequestFromSession(request);
    }

/*
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (logger.isDebugEnabled()){
            logger.debug("ReserveFieldStep4Controller.handleRequestInternal");
        }


        //ReservationField reservationField = getReservationFromSession(request);
         ReservationFieldRequest reservationFieldRequest = getReservationRequestFromSession(request);


        Collection<Club> clubs = clubManager.findAllClubsByRegionId(reservationFieldRequest.getRegionId());

        // putting the reservation and performance in session, for future reference.
        WebUtils.setSessionAttribute(request, "reservationFieldRequest", reservationFieldRequest);


        ModelAndView mav = new ModelAndView(getSuccessView());
        mav.addObject("regions", reservationFieldRequest.getRegions());
        mav.addObject("clubs", clubs);
        if (logger.isDebugEnabled()) {
            logger.debug("ModelAndView: "+mav.toString());
        }

        return mav;
    }
*/

    protected ModelAndView showForm(
            HttpServletRequest request, HttpServletResponse response, BindException errors, Map controlModel)
            throws Exception {

        //UserContext userContext = (UserContext) request.getSession().getAttribute(KeyConstant.USER_CONTEXT_KEY);
        UserContext userContext = (UserContext) WebUtils.getSessionAttribute(request, KeyConstant.USER_CONTEXT_KEY);

        if (userContext == null){
            // we must to redirect to login view

            // Fetch errors model as starting point, containing form object under
            // "commandName", and corresponding Errors instance under internal key.
            Map model = errors.getModel();

            // Merge control attributes into model, if any.
            if (controlModel != null) {
                model.putAll(controlModel);
            }
            ModelAndView mav = new ModelAndView(new RedirectView(getViewForward()));

            //String inputVieName = StringUtils.remove(request.getRequestURI(), request.getContextPath());
            String inputVieName = request.getRequestURI();

            mav.addObject(KeyConstant.VIEW_NAME_TO_RETURN_KEY, inputVieName);

            // Trigger rendering of the specified view, using the final model.
            return mav;
            //return new ModelAndView(new RedirectView(getViewForward()), model);
            //ModelAndView mav = new ModelAndView(getViewForward());
            //return showForm(request, errors, getViewForward(), controlModel);
        }

        return showForm(request, errors, getFormView(), controlModel);
    }

    /**
     * Binds the maximum number of seats the user will be able to select
     * (key = <code>maximumSeats</code>) and hte default selected value
     * (<code>defaultSelected</code>).
     */
    protected Map referenceData(HttpServletRequest request, Object o, Errors errors) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep5Controller.referenceData");
        }


        ReservationFieldRequest reservationFieldRequest = (ReservationFieldRequest)o;
        Map dataMap = new HashMap();

        UserContext userContext = (UserContext) request.getSession().getAttribute(KeyConstant.USER_CONTEXT_KEY);

        if (userContext == null){
            // we must to redirect to login view
            return dataMap;
        }


        User user = userManager.findUser(userContext.getId());

        Calendar reservationDate = Calendar.getInstance();
        reservationDate.setTime(reservationFieldRequest.getReservationDate());

        String startDateString = reservationFieldRequest.getStartHour();
        String endDateString = reservationFieldRequest.getStartHour();
        String[] times = startDateString.split("_");
        String hour = times[0];
        String minute = times[1];

        reservationDate.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hour));
        reservationDate.set(Calendar.MINUTE, Integer.valueOf(minute));
        reservationDate.set(Calendar.SECOND, 0);
        reservationDate.set(Calendar.MILLISECOND, 0);

        System.out.println("reservationDate getTime()= " + reservationDate.getTime());

        Timestamp startDate = new Timestamp(reservationDate.getTimeInMillis());

        times = endDateString.split("_");
        hour = times[0];
        minute = times[1];

        reservationDate.set(Calendar.HOUR_OF_DAY, Integer.valueOf(hour));
        reservationDate.set(Calendar.MINUTE, Integer.valueOf(minute));
        reservationDate.set(Calendar.SECOND, 0);
        reservationDate.set(Calendar.MILLISECOND, 0);

        System.out.println("reservationDate getTime()= " + reservationDate.getTime());

        Timestamp endDate = new Timestamp(reservationDate.getTimeInMillis());

        Turn reservedTurn = clubManager.saveReservationField(reservationFieldRequest.getFieldId(), startDate, endDate, user);

        dataMap.put("regions", reservationFieldRequest.getRegions());
        dataMap.put("reservedTurn", reservedTurn);

        return dataMap;
    }

    /**
     * @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(
     *      javax.servlet.http.HttpServletRequest,
            javax.servlet.http.HttpServletResponse,
            Object,
            org.springframework.validation.BindException)
     */
    protected ModelAndView onSubmit(HttpServletRequest httpRequest, HttpServletResponse httpResponse,
                                    Object o, BindException errors) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("ReserveFieldStep4Controller.onSubmit");
        }


        // the object is an already filled in reservation reservationFieldRequest
        ReservationFieldRequest reservationFieldRequest = (ReservationFieldRequest)o;


        // if errors occured showing the form view with the error messages.
        if ("sss" == null) {
            return showForm(httpRequest, errors, getFormView());
        }


        Collection<Club> clubs = clubManager.findAllClubsByRegionId(reservationFieldRequest.getRegionId());

        // putting the reservation and performance in session, for future reference.
        //WebUtils.setSessionAttribute(request, "reservationFieldRequest", reservationFieldRequest);


        ModelAndView mav = new ModelAndView(getSuccessView());
        mav.addObject("regions", reservationFieldRequest.getRegions());
        mav.addObject("clubs", clubs);

        /*
        // putting the reservation and performance in session, for future reference.
        WebUtils.setSessionAttribute(httpRequest, "reservationFieldRequest", reservationFieldRequest);

        // redirecting the another controller that will show the reservation.
        // this is done to prevent the user from resubmitting the form.
        reservationFieldRequest.setSuccessView(getSuccessView());

        ModelAndView mav = new ModelAndView(new RedirectView(getSuccessView()));
        if (logger.isDebugEnabled()) {
            logger.debug("ModelAndView: "+mav.toString());
        }
        */
        return mav;
    }



/*
    public RegionManager getRegionManager() {
        return regionManager;
    }

    public void setRegionManager(RegionManager regionManager) {
        this.regionManager = regionManager;
    }


    public ClubManager getClubManager() {
        return clubManager;
    }

    public void setClubManager(ClubManager clubManager) {
        this.clubManager = clubManager;
    }
*/
    //====================================== Helper Method (some used for testing) ====================================
}

